#if !defined(MOVE_HISTORY_H)
#define MOVE_HISTORY_H

#include <stdio.h>
#include <stack>
#include <string>
#include "ChessGame.h"
#include "Cell.h"
#include "Piece.h"

class Cell;
class Piece;
class ChessGame;

class MoveRecord {

	public:
		MoveRecord(Cell* homeCell, Cell* destCell,std::string color, std::string type) {
			this->homeCell = homeCell;
			this->destCell = destCell;
			this->color = color;
			this->type = type;
			if(homeCell != NULL)
				this->movedPiece = homeCell->GetPiece();
			if(destCell != NULL)
				this->displacedPiece = destCell->GetPiece();

		}

		Cell* GetHomeCell() {
			return homeCell;
		}
		Cell* GetDestCell() {
			return destCell;
		}
		Piece* GetMovedPiece() {
			return movedPiece;
		}
		Piece* GetDisplacedPiece() {
			return displacedPiece;
		}
		
		string toXmlString(){ 
			char col[21]; // enough to hold all numbers up to 64-bits
			char row[21]; // enough to hold all numbers up to 64-bits
			
			


			string output = "<move>";


			sprintf(col, "%d", this->GetHomeCell()->GetCol());
			sprintf(row, "%d",this->GetHomeCell()->GetRow());
			output += "<piece type=\""+this->getType()+"\" color=\""+this->getColor()+"\" row=\""+row+"\" column=\""+col+"\" />";

			sprintf(col, "%d", this->GetDestCell()->GetCol());
			sprintf(row, "%d",this->GetDestCell()->GetRow());
			output += "<piece type=\""+this->getType()+"\" color=\""+this->getColor()+"\" row=\""+row+"\" column=\""+col+"\" />";

			//Displaced piece if exists
			if(this->getDispType() != "")
				output += "<piece type=\""+this->getDispType()+"\" color=\""+this->getDispColor()+"\" row=\""+row+"\" column=\""+col+"\" />";

			output += "</move>";
			return output;
		}
		string getColor(){
			return color;
		}
		string getType(){
			return type;
		}
		string getDispType(){
			return dispType;
		}
		string getDispColor(){
			return dispColor;
		}
		void setDispColor(string newValue){
			this->dispColor = newValue;
		}
		void setDispType(string newValue){
			this->dispType = newValue;
		}
		void setDisplacedPiece(Piece * newpiece){
			this->displacedPiece = newpiece;
		}
	private:
		// store information on all pieces involves in the move
		Cell* homeCell;
		Cell* destCell;
		std::string type;
		std::string color;
		std::string dispType;
		std::string dispColor;

		Piece* movedPiece;
		Piece* displacedPiece;
};

class MoveHistory {

	public:

		MoveHistory() {

			moves = new std::stack<MoveRecord*>();

		}
		~MoveHistory(){
			//while(PopMostRecentMoveRecord()!=
			delete(moves);
		}

		void AddMove(Piece* piece, Cell* destCell) {

			MoveRecord* move = new MoveRecord(piece->GetCell(), destCell,piece->getColorString(),piece->getTypeString());
			moves->push(move);

		}
		void AddMoveRecord(MoveRecord * move){
			moves->push(move);
		}
		MoveRecord* PopMostRecentMoveRecord() {
			if(moves->size() == 0)
				return NULL;
			MoveRecord* top = moves->top();
			moves->pop();
			return top;
		}
		string toXmlString(){
			string output="";
			MoveHistory tempmoves;

			//Pop each move and put it to xml string
			while(moves->size() > 0 ){
				MoveRecord * temprecord = this->PopMostRecentMoveRecord();
				tempmoves.AddMoveRecord(temprecord);
				output = temprecord->toXmlString() + output;
			}
			//pop them from the temp stack and put them back into the normal stack
			while(tempmoves.moves->size() > 0)
				this->AddMoveRecord(tempmoves.PopMostRecentMoveRecord());

			return "<history>"+output+"</history>";
		}

	private:
		std::stack<MoveRecord*>* moves;

};

#endif
